package net.iceflow.dunsel.commons;

import java.util.Set;
import java.util.TreeSet;

/**
 * Tracks listeners that have subscribed.
 */
public class SubscriptionTracker<L, T> implements Subscribable<L> {

    /**
     * Registered listeners.
     */
    private final Set<L> _listeners = new TreeSet<L>();

    /**
     * Adapter to perform the actual notification to the listener.
     */
    private final ListenerCallAdapter<L, T> _adapter;

    /**
     * Constructs a new EventListenerTracker.
     */
    public SubscriptionTracker(ListenerCallAdapter<L, T> adapter) {
        this._adapter = adapter;
    }

    /**
     * Adds a listener.
     * @param listener Listener to add
     */
    @Override
    public void addListener(final L listener) {
        this._listeners.add(listener);
    }

    /**
     * Removes a listener.
     * @param listener Listener to remove
     */
    @Override
    public void removeListener(final L listener) {
        this._listeners.remove(listener);
    }

    /**
     * Removes all listeners.
     * @param listener Listener to remove
     */
    @Override
    public void removeAllListeners() {
        this._listeners.clear();
    }

    /**
     * Notifies the listeners
     * @param originator
     */
    public void notifyListeners(final T originator) {
        Event<T> event = new Event(originator);

        for (L listener : this._listeners) {
            this._adapter.callListener(event, listener);
        }
    }
}
